package mdb

import (
	"fmt"
	"gitee.com/dennis-mxx/mxx-core/mexception"
	"gitee.com/dennis-mxx/mxx-core/mlogger"
	"gitee.com/dennis-mxx/mxx-core/msystem"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
	"time"
)

var MySql *SQLExecute

func InitMysql() {
	if msystem.MysqlDataSource.Database == "" {
		return
	}
	if msystem.MysqlDataSource.Port == 0 {
		panic(mexception.NewException(mexception.NilException, "mysql.port is nil"))
	}
	if msystem.MysqlDataSource.Database == "" {
		panic(mexception.NewException(mexception.EmptyException, "mysql.port is empty"))
	}
	if msystem.MysqlDataSource.Username == "" {
		panic(mexception.NewException(mexception.EmptyException, "mysql.username is empty"))
	}
	if msystem.MysqlDataSource.Password == "" {
		panic(mexception.NewException(mexception.EmptyException, "mysql.password is empty"))
	}
	if msystem.MysqlDataSource.Host == "" {
		panic(mexception.NewException(mexception.EmptyException, "mysql.host is empty"))
	}

	if msystem.MysqlDataSource.MaxIdleConn == 0 {
		msystem.MysqlDataSource.MaxIdleConn = 5
	}
	if msystem.MysqlDataSource.MaxOpenConn == 0 {
		msystem.MysqlDataSource.MaxOpenConn = 600
	}
	if msystem.MysqlDataSource.Timeout == 0 {
		msystem.MysqlDataSource.Timeout = 30
	}

	db := ConnectionMysql(msystem.MysqlDataSource)
	if db != nil {
		MySql = &SQLExecute{DB: db, ShowSql: msystem.MysqlDataSource.ShowSql}
		mlogger.Logger.Info(fmt.Sprintf("connection mysql database [%s:%v][%s] successful ", msystem.MysqlDataSource.Host, msystem.MysqlDataSource.Port, msystem.MysqlDataSource.Database))
	} else {
		panic(fmt.Sprintf("connection mysql database [%s] failure ", msystem.MysqlDataSource.Database))
	}
}

func ConnectionMysql(dataSource *msystem.MysqlOptions) *sqlx.DB {

	defer mlogger.FormatException()
	driverName := fmt.Sprintf(
		`%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=true&multiStatements=true&loc=UTC`,
		dataSource.Username,
		dataSource.Password,
		dataSource.Host,
		dataSource.Port,
		dataSource.Database,
	)
	db := sqlx.MustConnect(`mysql`, driverName)
	timeout := time.Duration(dataSource.Timeout)
	db.DB.SetMaxOpenConns(dataSource.MaxOpenConn)        // 用于设置最大打开的连接数，默认值为0表示不限制
	db.DB.SetMaxIdleConns(dataSource.MaxIdleConn)        // 用于设置闲置的连接数
	db.DB.SetConnMaxLifetime(timeout * time.Millisecond) // 设置一个超时时间，时间小于数据库的超时时间即可
	return db
}
